import classNames from 'classnames';
import React, { ReactNode, useCallback } from 'react'
import '@/app/component/form.css'

/** 单个选项的结构 */
export interface SelectOption<T = string> {
  label: ReactNode; // 选项显示内容
  value: T; // 选项实际值（支持任意类型）
  [key: string]: any; // 允许扩展其他属性
}
/** 辅助类型：根据多选状态推导值类型 */
type SelectValue<T, IsMultiple> = IsMultiple extends true ? T[] | undefined : T | undefined;

/** 
 * MySelect 组件属性接口
 * @template T 选项值的类型（如 string、number、object 等）
 * @template IsMultiple 是否为多选模式（boolean 类型字面量）
 */
export interface SelectProps<T = string, IsMultiple extends boolean = false> {
  options: SelectOption<T>[]; // 选项列表
  multiple?: IsMultiple; // 是否开启多选（与 IsMultiple 泛型绑定）
  value: SelectValue<T, IsMultiple>; // 选中值（根据 IsMultiple 动态推导）
  onChange: (value: SelectValue<T, IsMultiple>) => void; // 回调参数类型与 value 一致
  disabled?: boolean; // 禁用整个组件
  className?: string; // 自定义容器类名
  optionSuffix?: ReactNode
  optionPrefix?: ReactNode
}
function MyPlatSelect<T, IsMultiple extends boolean = false> ({
  options,
  multiple,
  value,
  onChange,
  className,
  optionPrefix,
  optionSuffix,
}: SelectProps<T, IsMultiple>) {
  // 选择方法处理 -------------------------------------------------------------------------------
  // 单选
  const handleSingleSelect = useCallback(
    (option: SelectOption<T>) => {
      // 单选时，value 为 T | undefined， newValue 类型匹配
      const newValue = value === option.value ? undefined : option.value;
      onChange(newValue as SelectValue<T, IsMultiple>);
    },
    [value, onChange]
  );

  // 多选
  const handleMultiSelect = useCallback(
    (option: SelectOption<T>) => {
      // 多选时，value 为 T[] | undefined
      const currentValues = Array.isArray(value) ? [...value] : [];
      const isMultiSelected = currentValues.includes(option.value);

      let newValue: T[] | undefined;
      if (isMultiSelected) {
        newValue = currentValues.filter((v) => v !== option.value);
        if (newValue.length === 0) newValue = undefined;
      } else {
        newValue = [...currentValues, option.value];
      }
      onChange(newValue as SelectValue<T, IsMultiple>);
    },
    [value, onChange]
  );

  // option渲染 -------------------------------------------------------------------------------
  // 单选
  const singleOption = (option: SelectOption<T>) => <div className={classNames('plat-select-option', {
    'plat-select-option--active': isSingleSelected(option)
  }, className)}>
    {optionPrefix}
    <div className='plat-select-option-text'>
      {option.label}
    </div>
    {optionSuffix}
  </div>

  // 多选
  const multiOption = (option: SelectOption<T>) => <div className={classNames('plat-select-option', {
    'plat-select-option--active': isMultiSelected(option)
  }, className)}>
    {optionPrefix}
    <div className='plat-select-option-text'>
      {option.label}
    </div>
    {optionSuffix}
  </div>

   // 判断option是否是选中状态 -------------------------------------------------------------------------------
  // 单选(通过value判断)
  const isSingleSelected = (option: SelectOption<T>) => {
    if (multiple) {
      return Array.isArray(value) && value.includes(option.value)
    }
    return value === option.value
  }

  // 多选(通过tempValue判断)
  const isMultiSelected = (option: SelectOption<T>) => {
    if (multiple) {
      return Array.isArray(value) && value.includes(option.value)
    }
    return value === option.value
  }

  return (
    <ul className={`plat-select-layout`}>
      {options.map((option, index) => (
        <li onClick={
          () => {
            if (multiple) {
              handleMultiSelect(option)
            } else {
              handleSingleSelect(option)
            }
          }
        } key={index}>
          {multiple ? multiOption(option) : singleOption(option)}
        </li>
      ))}
    </ul>
  )
}

export default MyPlatSelect